package com.cdty.chess.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@Component // 声明为Spring管理的Bean
public class MyWebSocketHandler extends TextWebSocketHandler {
    private final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>();

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        try {
            ObjectMapper mapper = new ObjectMapper();
            Map<String, Object> msgMap = mapper.readValue(message.getPayload(), Map.class);

            // 处理心跳消息
            if ("heartbeat".equals(msgMap.get("event"))) {
                String response = mapper.writeValueAsString(Map.of(
                        "event", "heartbeat",
                        "data", "pong"
                ));
                session.sendMessage(new TextMessage(response));
                return;
            }

            // 其他消息处理逻辑...

        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    // 添加定时连接检查（可选）
    @Scheduled(fixedRate = 60000) // 每分钟检查一次
    public void checkConnections() {
        sessions.removeIf(session -> {
            try {
                // 发送Ping消息检测连接
                if (session.isOpen()) {
                    session.sendMessage(new TextMessage("{\"event\":\"ping\"}"));
                    return false;
                }
                return true;
            } catch (IOException e) {
                return true;
            }
        });
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        Map<String, String> params = extractQueryParams(session.getUri());
        String userId = params.getOrDefault("userId", "unknown");
        Boolean master = Boolean.parseBoolean(params.getOrDefault("master", "false"));
        // 关闭同一用户的旧连接
        sessions.stream()
                .filter(s -> userId.equals(s.getAttributes().get("userId")))
                .forEach(s -> {
                    try {
                        s.close(CloseStatus.NORMAL); // 正常关闭旧连接
                    } catch (IOException e) {
                        // 忽略异常
                    }
                });
        sessions.removeIf(s -> !s.isOpen()); // 清理无效连接

        // 将用户ID和角色保存到session属性中
        session.getAttributes().put("userId", userId);
        session.getAttributes().put("master", master);

        sessions.add(session);
        this.getOnlineCount();
        System.out.println("New connection: " + session.getId());

    }

    /**
     * 获取在线人数
     */
    private void getOnlineCount() {
        // 清理无效的Session
        sessions.removeIf(s -> !s.isOpen());
        int size = sessions.size();
        ObjectMapper mapper = new ObjectMapper();
        try {
            String msg = mapper.writeValueAsString(Map.of(
                    "event", "pCount",
                    "data",Map.of("pcount",String.valueOf(size))
            ));
            // 遍历所有Session发送消息
            sessions.forEach(session -> {
                //Boolean master = (Boolean) session.getAttributes().get("master");
                if (session.isOpen()) {
                    try {
                        session.sendMessage(new TextMessage(msg));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }

            });
        } catch (JsonProcessingException e ) {
            System.err.println("消息发送失败: " + e.getMessage());
        }

    }

    // 辅助方法：解析URL中的查询参数
    private Map<String, String> extractQueryParams(URI uri) {
        Map<String, String> params = new HashMap<>();
        if (uri != null && uri.getQuery() != null) {
            String query = uri.getQuery();
            String[] pairs = query.split("&");
            for (String pair : pairs) {
                String[] keyValue = pair.split("=");
                if (keyValue.length == 2) {
                    try {
                        // URL解码处理特殊字符（如空格、中文）
                        String key = URLDecoder.decode(keyValue[0], "UTF-8");
                        String value = URLDecoder.decode(keyValue[1], "UTF-8");
                        params.put(key, value);
                    } catch (UnsupportedEncodingException e) {
                        // 忽略解码错误
                    }
                }
            }
        }
        return params;
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        sessions.remove(session);
        this.getOnlineCount();
        System.out.println("Connection closed: " + session.getId());
    }

    // 广播所有用户
    public void broadcastAll(String message) {
        // 清理无效的Session
        sessions.removeIf(s -> !s.isOpen());

        // 遍历所有Session发送消息
        sessions.forEach(session -> {
            try {
                if (session.isOpen()) {
                    session.sendMessage(new TextMessage(message));
                }
            } catch (IOException e) {
                System.err.println("消息发送失败: " + e.getMessage());
            }
        });
    }

    // 广播当前用户
    public void broadToUid(String uid,String message) {
        // 清理无效的Session
        sessions.removeIf(s -> !s.isOpen());

        // 遍历所有Session给特定用户发送消息
        sessions.forEach(session -> {
            try {
                // 获取用户的业务ID和角色
                String userId = (String) session.getAttributes().get("userId");
               // Boolean master = (Boolean) session.getAttributes().get("master");
                if (session.isOpen()&&userId.equals(uid)) {
                    session.sendMessage(new TextMessage(message));
                }
            } catch (IOException e) {
                System.err.println("消息发送失败: " + e.getMessage());
            }
        });
    }

    //广播管理员和自己
    public void broadMasterAndUid(String uid, String msg) {

        // 清理无效的Session
        sessions.removeIf(s -> !s.isOpen());

        // 遍历所有Session给特定用户发送消息
        sessions.forEach(session -> {
            try {
                // 获取用户的业务ID和角色
                String userId = (String) session.getAttributes().get("userId");
                Boolean master = (Boolean) session.getAttributes().get("master");

                // 判断是否是管理员或者目标用户
                if (session.isOpen()) {
                    if (master ||userId.equals(uid)) {
                        session.sendMessage(new TextMessage(msg));
                    }
                }
            } catch (IOException e) {
                System.err.println("消息发送失败: " + e.getMessage());
            }
        });
    }

    /**
     * 给管理员发送消息
     * @param msg
     */
    public void broadToMaster(String msg) {

        // 清理无效的Session
        sessions.removeIf(s -> !s.isOpen());

        // 遍历所有Session给特定用户发送消息
        sessions.forEach(session -> {
            try {
                // 获取用户的业务ID和角色
                Boolean master = (Boolean) session.getAttributes().get("master");
                // 判断是否是管理员或者目标用户
                if (session.isOpen()) {
                    if (master ) {
                        session.sendMessage(new TextMessage(msg));
                    }
                }
            } catch (IOException e) {
                System.err.println("消息发送失败: " + e.getMessage());
            }
        });
    }
}